home *** CD-ROM | disk | FTP | other *** search
- /*
- Triangle operations
- */
- #include <graphics.h>
- #include <float.h>
- #include <math.h>
-
- typedef struct {
- float row[3];
- float col[3];
- } triangle;
-
- #include "fdesign.h"
- #include "fdesequa.h"
- #include "fdesfile.h"
- #include "fdesmenu.h"
- #include "fdesmous.h"
- #include "fdesplot.h"
-
- /* ****************************************************************** */
- int triangle_new(triangle *t,int tcolor) /* input triangle coordinates from mouse */
- {
- int rcode;
- mouse_state m;
- rcode = mouse_click_grat(&m); /* point 1 of triangle */
- if (rcode&0x02) return(rcode);
- setcolor(tcolor);
- (*t).row[0] = m.row;
- (*t).col[0] = m.col;
- outtextxy(m.col,m.row,"A");
- mouse_click_grat(&m); /* point 2 of triangle */
- (*t).row[1] = m.row;
- setcolor(tcolor);
- outtextxy(m.col,m.row,"B");
- (*t).col[1] = m.col;
- line((*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
- rcode = mouse_click_grat(&m); /* point 3 of triangle */
- setcolor(tcolor);
- (*t).row[2] = m.row;
- (*t).col[2] = m.col;
- outtextxy(m.col,m.row,"C");
- line((*t).col[1],(*t).row[1],(*t).col[2],(*t).row[2]);
- line((*t).col[2],(*t).row[2],(*t).col[0],(*t).row[0]);
- return(rcode);
- }
-
- void triangle_show(triangle *t)
- {
- line((*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
- outtextxy((*t).col[0],(*t).row[0],"A");
- line((*t).col[1],(*t).row[1],(*t).col[2],(*t).row[2]);
- outtextxy((*t).col[1],(*t).row[1],"B");
- line((*t).col[2],(*t).row[2],(*t).col[0],(*t).row[0]);
- outtextxy((*t).col[2],(*t).row[2],"C");
- }
-
- /*
- Distance of a point to a point
- */
- float pt_pt_distance(float x1, float y1, float x2, float y2)
- {
- float d2;
- d2 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
- if (d2 == 0.0) return (0.0);
- else return (sqrt(d2));
- }
- /*
- Return closest triangle corner ( 0 1 or 2 )
- */
- int triangle_corner(triangle *t, float col, float row)
- {
- float a,b,c;
- a = pt_pt_distance((*t).row[0],(*t).col[0],row,col);
- b = pt_pt_distance((*t).row[1],(*t).col[1],row,col);
- c = pt_pt_distance((*t).row[2],(*t).col[2],row,col);
- if ((a<b)&&(a<c)) return(0);
- if (b<c) return(1);
- else return(2);
- }
- /*
- Distance of a point to a line
- */
- float pt_line_distance(float x, float y, float x1, float y1, float x2, float y2)
- {
- float a,b,e,c;
- if ((x==x1) && (y==y1)) a = 0.0;
- else a = sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
- if ((x==x2) && (y==y2)) b = 0.0;
- else b = sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
- if ((x1==x2) && (y1==y2)) e = 0.0;
- else e = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
- if (e != 0.0)
- {
- c = (b*b - a*a - e*e)/(-2*e);
- if ((a*a-c*c) < 0.0) return(0.0);
- else return(sqrt(a*a-c*c));
- }
- else
- return(a);
- }
- /*
- Distance of a point to a line SEGMENT
- (to locate nearest triangle edge)
- */
- float pt_lines_distance(float x, float y, float x1, float y1, float x2, float y2)
- {
- float a,b,e,c;
- if ((x==x1) && (y==y1)) a = 0.0;
- else a = sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
- if ((x==x2) && (y==y2)) b = 0.0;
- else b = sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));
- if ((x1==x2) && (y1==y2)) e = 0.0;
- else e = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
- if ((a*a + e*e) < (b*b)) return(a);
- if ((b*b + e*e) < (a*a)) return(b);
- if (e != 0.0)
- {
- c = (b*b - a*a - e*e)/(-2*e);
- if ((a*a-c*c) < 0.0) return(0.0);
- else return(sqrt(a*a-c*c));
- }
- else
- return(a);
- }
- float pt_triangle_distance(float x, float y, triangle *t)
- {
- float n1,n2,n3;
- n1 = pt_lines_distance(x,y,(*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
- n2 = pt_lines_distance(x,y,(*t).col[1],(*t).row[1],(*t).col[2],(*t).row[2]);
- n3 = pt_lines_distance(x,y,(*t).col[2],(*t).row[2],(*t).col[0],(*t).row[0]);
- if (n2 < n1) n1 = n2;
- if (n3 < n1) n1 = n3;
- return(n1);
- }
- /*
- Finds the triangle closest to the point specified.
- Returns the triangle number or -1 if the reference triangle.
- */
- int pt_closest_triangle(float x, float y)
- {
- float dist[MAXFUNC];
- float dist_ref;
- int i;
- int best_t;
- dist_ref = pt_triangle_distance(x,y,&triangle0);
- /* gotoxy(1,12); printf("%6f",dist_ref);
- */ for (i=0; i<num_triangles; i++)
- {
- dist[i] = pt_triangle_distance(x,y,&triangles[i]);
- /* printf(" %6f",dist[i]);
- */ }
- /* find minimum */
- best_t = 0;
- for (i=(num_triangles - 1); i>0; i--)
- {
- if (dist[i] < dist[0])
- {
- dist[0] = dist[i];
- best_t = i;
- }
- }
-
- if (dist_ref < dist[0]) return(-1);
- else return(best_t);
- }
- /*
- Find triangle area.
- Collapsed triangles (base or height = 0) will have an area assuming
- one pixel width (instead of zero).
- */
- float triangle_area(triangle *t)
- {
- float base,height;
- /* area is 1/2 base times height */
- base = pt_pt_distance((*t).col[0],(*t).row[0],(*t).col[1],(*t).row[1]);
- height = pt_line_distance((*t).col[2],(*t).row[2],(*t).col[1],(*t).row[1],
- (*t).col[0],(*t).row[0]);
- if (base < 1.0) return(5.0*height); /* && 3.0 was 1.0 */
- else if (height < 1.0) return(5.0*base); /* && 3.0 was 1.0 */
- else return(0.5*base*height);
- }
-
- /************************************************************************
- Transformation Check if affine
- ************************************************************************/
- int transform_affine(triangle *t) /* return 0 if not affine */
- {
- float ra,rb,rc;
- float a,b,c;
- ra = pt_pt_distance(triangle0.row[0],triangle0.col[0],
- triangle0.row[1],triangle0.col[1]);
- rb = pt_pt_distance(triangle0.row[1],triangle0.col[1],
- triangle0.row[2],triangle0.col[2]);
- rc = pt_pt_distance(triangle0.row[2],triangle0.col[2],
- triangle0.row[0],triangle0.col[0]);
- a = pt_pt_distance((*t).row[0],(*t).col[0],(*t).row[1],(*t).col[1]);
- b = pt_pt_distance((*t).row[1],(*t).col[1],(*t).row[2],(*t).col[2]);
- c = pt_pt_distance((*t).row[2],(*t).col[2],(*t).row[0],(*t).col[0]);
- if (a > ra) return(0);
- if (b > rb) return(0);
- if (c > rc) return(0);
- if ((a == ra) && (b == rb) && (c == rc)) return(0);
- return(1);
- }
- /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
- Find screen limits of Triangles
- (used to re-orient Triangles on screen)
- *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
- void triangles_limits(float *left,float *up,float *right,float *down)
- {
-
- int i,j;
- *left = *right = triangle0.col[0];
- *up = *down = triangle0.row[0];
-
- for (i=0; i<3; i++)
- {
- if (triangle0.row[i] < *up) *up = triangle0.row[i];
- if (triangle0.row[i] > *down) *down = triangle0.row[i];
- if (triangle0.col[i] < *left) *left = triangle0.col[i];
- if (triangle0.col[i] > *right) *right = triangle0.col[i];
- }
- for (j=0; j<num_triangles; j++)
- {
- for (i=0; i<3; i++)
- {
- if (triangles[j].row[i] < *up) *up = triangles[j].row[i];
- if (triangles[j].row[i] > *down) *down = triangles[j].row[i];
- if (triangles[j].col[i] < *left) *left = triangles[j].col[i];
- if (triangles[j].col[i] > *right) *right = triangles[j].col[i];
- }
- }
- }
-
-
-
-
-